// --- Copyright (c) 2006-2008 Stefan Kyntchev ---
// This software is written and copyrighted by Stefan Kyntchev 
// and BeyondPod Team members. All rights are reserved.
// Author contact: support@beyondpod.mobi
// ------------------------------------------------------------------------
// This file is part of BeyondPod RSS Feed Reader and Podcast manager
// (www.codeplex.com/BeyondPod) 
// BeyondPod is free software: you can redistribute it and/or modify 
// it under the terms of the GNU General Public License as published by 
// the Free Software Foundation, either version 3 of the License, or 
// (at your option) any later version. 
//  
// BeyondPod is distributed in the hope that it will be useful, 
// but WITHOUT ANY WARRANTY; without even the implied warranty of 
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
// GNU General Public License for more details. 
//  
// You should have received a copy of the GNU General Public License
// along with BeyondPod. If not, see <http://www.gnu.org/licenses/>
// ------------------------------------------------------------------------
// COPYRIGHT NOTICE: This copyright notice may NOT be removed, obscured or modified 
// without written consent from the author.
// --- End copyright notice --- 


using System;
using System.Collections.Generic;
using System.IO;
using svs.Mobile.BeyondMedia.FeedCore.Helpers;
using svs.Mobile.BeyondMedia.FeedCore.RSS.Entities;

namespace svs.Mobile.BeyondMedia.FeedCore.RSS.Templates
{
	public class RssTemplatingEngine
	{
		private const string DOWNLOAD_ENCODE_KEY = "&beyondpod_action=download";
		private const string STREAM_ENCODE_KEY = "&beyondpod_action=stream";
		private const string ITEM_DESC_VISIBILITY_IMG_COLLAPSED = @"..\RSSTemplates\img\hdr_clp.png";
		private static readonly ErrorMessageTemplate m_ErrorTmpl = new ErrorMessageTemplate(TemplateBase.TemplateTypes.RSS);
		private static readonly InfoMessageTemplate m_InfoTmpl = new InfoMessageTemplate(TemplateBase.TemplateTypes.RSS);

		public static string FormatFeedLoadError(string name, string message)
		{
			return String.Format("<html><body><p align='center' style='color:{0}; font-weight: bold; margin-top: 20px; font-size: 12pt;'>{1}</p>", CoreHelper.SYS_COLOR_A, name) +
						String.Format("<div style='color: Maroon; text-align:center; font-size: 10pt;'>{0}</div></body></html>", message);
		}

		public static bool TransformFeedLoadError(string name, string anError, string SavePath)
		{
			m_ErrorTmpl.FeedName = name;
			m_ErrorTmpl.Message = anError;
			return m_ErrorTmpl.SaveAsHtml(SavePath);
		}

		public static bool TransformNoCachedFeedInfo(string name,string SavePath)
		{
			m_InfoTmpl.FeedName = name;
			return m_InfoTmpl.SaveAsHtml(SavePath);
		}

		public static bool BuildTTSView(string savePath, RssFeed rssfeed, Feed feed, int pageSize, bool hideReadItems)
		{
			ReloadAlltemplates();

			var doc = new DocumentTemplate(savePath, pageSize, TemplateBase.TemplateTypes.TTS)
			          	{
			          		HideReadItems = hideReadItems,
			          		LastRetrievalDate = rssfeed.LastRetrievalDate.ToLocalTime(),
			          		IsAggregateFeed = rssfeed.IsAggregateFeed
			          	};

			if (rssfeed.IsOld)
			{
				doc.FeedAge = rssfeed.DaysOld;
			}

			LoadFeedList(doc, rssfeed, feed);

			bool saved = doc.SaveAsHtml();

			ReloadAlltemplates();

			return saved;
		}


		public static bool BuildRssView(string savePath, RssFeed rssfeed, Feed feed, int pageSize, bool hideReadItems)
		{
			DocumentTemplate doc = new DocumentTemplate(savePath, pageSize, TemplateBase.TemplateTypes.RSS);

			doc.HideReadItems = hideReadItems;
			doc.LastRetrievalDate = rssfeed.LastRetrievalDate.ToLocalTime();
			doc.IsAggregateFeed = rssfeed.IsAggregateFeed;

			if (rssfeed.IsOld)
			{
				doc.FeedAge = rssfeed.DaysOld;
			}

			LoadFeedList(doc, rssfeed, feed);
			return doc.SaveAsHtml();
		}

		public static string EncodeDownloadEnclosureUrl(string i_url)
		{
			return i_url + DOWNLOAD_ENCODE_KEY;
		}

		public static string EncodeStreamEnclosureUrl(string i_url)
		{
			return i_url + STREAM_ENCODE_KEY;
		}

		public static string DecodeDownloadEnclosureUrl(string i_url)
		{
			return i_url.Replace(DOWNLOAD_ENCODE_KEY, string.Empty);
		}

		public static string DecodeStreamEnclosureUrl(string i_url)
		{
			return i_url.Replace(STREAM_ENCODE_KEY, string.Empty);
		}

		public static bool IsDownloadEncodedEnclosureUrl(string i_url)
		{
			return i_url.EndsWith(DOWNLOAD_ENCODE_KEY);
		}

		public static bool IsStreamEncodedEnclosureUrl(string i_url)
		{
			return i_url.EndsWith(STREAM_ENCODE_KEY);
		}

		private static void LoadFeedList(DocumentTemplate i_doc, RssFeed i_rssFeed, Feed feed)
		{
			FeedTemplate feedTemplate = new FeedTemplate(i_doc.TemplateType);
			feedTemplate.Title = i_rssFeed.Title;
			feedTemplate.Description = i_rssFeed.Description;
			feedTemplate.Link = i_rssFeed.Link;
			feedTemplate.LastBuildDate = i_rssFeed.PubDate.HasValue ? CoreHelper.FormatDateTime(i_rssFeed.PubDate.Value.ToLocalTime()) : string.Empty;

			int downloadableEnclosures = i_rssFeed.GetDownloadableEnclosures().Count;
			feedTemplate.DownloadAllText =  downloadableEnclosures == 0
			                       	? string.Empty
			                       	: string.Format("Download All {0} New Podcasts", i_rssFeed.GetDownloadableEnclosures().Count);

			feedTemplate.ShowAllText = feed.Tracks.Count > 0 ? "View Local Podcasts" : string.Empty;
			feedTemplate.LinkPrefix = Configuration.LinkPrefix;

			if (downloadableEnclosures > 0)
			{
				long? freeSpace = FlashStorageLocation.GetFreeSpaceAtFeedDownloadPath(feed);
				feedTemplate.FreeSpaceForDownload = freeSpace.HasValue ? string.Format("(You have {0} of free space)", CoreHelper.GetFileLengthAsString(freeSpace)) : string.Empty;
			}
			else
			{
				feedTemplate.FreeSpaceForDownload = string.Empty;
			}

			i_doc.Feed = feedTemplate;
			LoadFeedItemList(i_doc, i_rssFeed.Items);
		}

		private static void LoadFeedItemList(DocumentTemplate i_doc, List<RssFeedItem> items)
		{
			if (items.Count == 0)
				return;

			CoreHelper.WriteTraceEntry("Loading Feed Item List into the template...");

			int AutocollapseLevel = Configuration.AutoCollapseLevel;

			int sequenceID = 1;
			Guid lastOriginatingFeedID = Guid.Empty;
			for (int feedNum = 0; feedNum != items.Count; feedNum ++)
			{
				RssFeedItem feedItem = items[feedNum];

				//For aggregate feeds insert the feed name for the next group of items
				if (i_doc.IsAggregateFeed && (lastOriginatingFeedID == Guid.Empty ||  lastOriginatingFeedID != feedItem.OriginatingFeedID))
				{
					var t = new OriginatingFeedNametemTemplate(i_doc.TemplateType);
					var owner = FeedRepository.GetFeedById(feedItem.OriginatingFeedID);
					
					if(owner != null)
						t.Title = owner.Name;

					i_doc.Items.Add(t);

					lastOriginatingFeedID = feedItem.OriginatingFeedID;
				}
				
				//Check if we need to hide the unread items
				if (i_doc.HideReadItems && feedItem.Read)
				{
					i_doc.HasHiddenReadItems = true;
					continue;
				}

				FeedItemTemplate item = new FeedItemTemplate(i_doc.TemplateType);

				item.Title = feedItem.Title;
				item.Description = item.TemplateType == TemplateBase.TemplateTypes.RSS ? feedItem.Description : feedItem.TaglessDescription;
				item.Link = feedItem.Link;
				item.FeedItemID = feedItem.ItemID.HasValue?feedItem.ItemID.ToString():"0";
				item.LinkPrefix = Configuration.LinkPrefix;
				item.ImageFolder = Configuration.RssTemplatesImagePath;

				if (feedItem.Enclosure != null)
				{
					item.EnclosureInHistory = feedItem.Enclosure.EnclosureInHistory;

					if (feedItem.Enclosure.Downloaded)
					{
						item.EnclosureIsDownloaded = true;
						item.EnclosureLink = Uri.UriSchemeFile + @":\\" + feedItem.Enclosure.LocalFileName;
						item.EnclosureAction = "Play";
						item.EnclosureDeleteAction = "Delete";
					}
					else
					{
						item.EnclosureLink = EncodeDownloadEnclosureUrl(feedItem.Enclosure.Url);
						item.EnclosureStreamLink = EncodeStreamEnclosureUrl(feedItem.Enclosure.Url);

						if (!feedItem.Enclosure.EnclosureInHistory)
							item.EnclosureAction = "Download";
						else
							item.EnclosureAction = "Download Again";

						item.EnclosureStreamAction = "Stream";
					}

					if (string.IsNullOrEmpty(feedItem.Enclosure.EnclosureSizeAsString))
						item.EnclosureFileSize = string.Empty;
					else
						item.EnclosureFileSize = "(" + feedItem.Enclosure.EnclosureSizeAsString + ")";

					item.EnclosureFileName = feedItem.Enclosure.FileName;
					item.EnclosureVisibility = "block";
				}
				else
				{
					item.EnclosureDeleteAction = item.EnclosureAction = item.EnclosureStreamAction = item.EnclosureFileName = item.EnclosureFileSize = item.EnclosureLink = item.EnclosureStreamLink = string.Empty;
					item.EnclosureVisibility = "none";
				}

				item.FeedItemSequenceID = sequenceID.ToString();

				if ((AutocollapseLevel == -2 && feedItem.Read) || (AutocollapseLevel >= 0 && (feedItem.Description.Length >= AutocollapseLevel || feedItem.Read)) )
				{
					item.DescriptionVisibility = "none";
					item.ToggleText = "More";
					item.ToggleVisibility = "block";
				}
				else
				{
					item.DescriptionVisibility = "block";
					item.ToggleText = "Hide";
					item.ToggleVisibility = "block";
				}

				item.ReadText = feedItem.Read ? "Unread" : "Read";
				item.ReadStatusColor = feedItem.Read ? "silver" : CoreHelper.SYS_COLOR_A;

				item.PublishedDate = feedItem.PubDate.HasValue ? CoreHelper.FormatDateTime(feedItem.PubDate.Value.ToLocalTime()): string.Empty;

				i_doc.Items.Add(item);

				sequenceID++;
			}

			CoreHelper.WriteTraceEntry("DONE Loading Feed Item List into the template!");

		}

		public static void ReloadAlltemplates()
		{
			DocumentTemplate.RefreshTemplate();
			FeedItemTemplate.RefreshTemplate();
			FeedLastUpdateTemplate.RefreshTemplate();
			FeedOldTemplate.RefreshTemplate();
			FeedTemplate.RefreshTemplate();
			InfoMessageTemplate.RefreshTemplate();
			NextPageTemplate.RefreshTemplate();
			PrevPageTemplate.RefreshTemplate();
		}
	}
}